home *** CD-ROM | disk | FTP | other *** search
-
- IBM Mazes and Movement
- (COMPUTE! Magazine May 1986)
-
- This article discusses how to write a maze game to randomly
- generate a simple maze allowing one to choose the dimensions and
- still make it solvable. Few COMPUTE! programs have spawned so many
- offspring as Charles Bond's maze generation algorithm originally
- published in the December 1981 issue. This is an adaptation for
- SCREEN 1, the medium-resolution graphics screen. In place of the
- PEEKs and POKEs of the earlier versions, this one uses BASIC's
- SCREEN, LOCATE, and PRINT statements:
-
- 100 KEY OFF:SCREEN 1,0:COLOR 1,0:CLS:RANDOMIZE TIMER
- 110 MAXROW=23:MAXCOL=40:DIM P(3,1):FOR J=0 TO 3:READ P(J,0),P(J,1):NEXT
- 120 DATA 0,2,-2,0,0,-2,2,0
- 130 HL=8:YPOS=2:XPOS=2:LOCATE YPOS,XPOS:PRINT CHR$(5)
- 140 J=INT(RND(1)*4):X=J
- 150 NY=YPOS+P(J,0):NX=XPOS+P(J,1):IF NY<1 OR NY>MAXROW OR NX<1 OR NX>MAXCOL THEN 170
- 160 IF SCREEN(NY,NX)=0 THEN LOCATE NY,NX:PRINT CHR$(J+1):LOCATE (YPOS+P(J,0)/2),(XPOS+P(J,1)/2):PRINT CHR$(HL):YPOS=NY:XPOS=NX:GOTO 140
- 170 J=(J+1)*-(J<3):IF J<>X THEN 150
- 180 J=SCREEN(YPOS,XPOS)-1:LOCATE YPOS,XPOS:PRINT CHR$(HL);:IF J<4 THEN YPOS=YPOS-P(J,0):XPOS=XPOS-P(J,1):GOTO 150
- 190 GOTO 190
-
- To customize the routine for your own use, change MAXROW and
- MAXCOL (line 110) for the maximum number of rows and columns in the
- maze. (Don't make MAXROW greater than 23, since printing on the
- bottom two lines of the screen causes scrolling.) As it stands now,
- the routine always starts constructing the maze from the upper-left
- corner. You can change this by changing the values of XPOS and YPOS
- (line 130). The values should always be at least 2, but less than
- MAXROW and MAXCOL. The variable HL (line 130) defines the character
- used for the paths of the maze. You can change this to any character
- you desire, but its value must be greater than 5 (lower values are
- used to draw the maze) and less than 128 (higher values are not
- available on the graphics screen). Unfortunately, this set of
- characters does not include a reverse space that would draw solid
- paths for the maze. It's up to you to define which end point is the
- finish of the maze.
-
- Now that the maze is in place, it's an ideal time to address
- use of the joystick. The joystick is nice to maneuver a player
- through the maze, and BASIC's STICK and STRIG functions make it easy
- to read. IBM joysticks are "positional"; they return values that
- reflect the horizontal and vertical deflection of the stick relative
- to a simple coordinate system. In this system, coordinate 0,0 means
- the stick is pushed to the upper-left corner, and 255,255 means the
- stick is pushed to the lower-right corner. STICK(0) returns the
- horizontal (x) coordinate of the first joystick, while STICK(1)
- returns the vertical (y) coordinate. STICK(2) and STICK(3) perform
- the corresponding functions for the second joystick. The only
- special rule is that STICK(0) must be read first, before any other
- directions. (Even if you only want positions from the second
- joystick, you must read STICK(0) first.)
-
- STRIG reads the status of the joystick buttons -- most IBM
- joysticks have two, but only one per joystick can be read unless
- you're using BASICA. You must use the statement STRIG ON before you
- can read button status. After enabling button reading, STRIG(0)
- returns -1 if the primary button on the first joystick has been
- pressed since the last time STRIG(0) was called, or 0 if it has not
- been pressed. STRIG(1) is slightly different -- it returns -1 if the
- primary button on the first joystick is currently pressed (regardless
- of its previous state), or 0 if it is not pressed. STRIG(2) and
- STRIG(3) perform the corresponding functions for the primary button
- on the second joystick.
-
- This system makes it easy to determine the position of the
- joystick. But in a situation like navigating the maze drawn by the
- routine above, what you really need to know is the direction in which
- the stick is pressed. Add the lines below to the maze-drawing routine:
-
- 190 CH=1:XPOS=2:XPOS=2:LOCATE YPOS,XPOS:PRINT CHR$(CH)
- 200 XMOV=STICK(0)-XCTR:XJOY=SGN(XMOV):IF ABS(XMOV)<10 THEN XJOY=0
- 210 YMOV=STICK(1)-YCTR:YJOY=SGN(YMOV):IF ABS(YMOV)<10 THEN YJOY=0
- 220 NY=YPOS+YJOY:NX=XPOS+XJOY:IF NY<1 OR NY>23 OR NX<1 OR NX>40 THEN 200
- 230 IF SCREEN(NY,NX)=0 THEN 200
- 240 LOCATE YPOS,XPOS:PRINT CHR$(8):LOCATE NY,NX:PRINT CHR$(1):YPOS=NY:XPOS=NX:GOTO 200
-
- Line 190 defines character 1 (the reverse smiling face) as the
- player, then positions it at the start of the maze. Lines 200-210
- calculate two directional values, XJOY and YJOY, based on how far the
- stick is moved from the center positions (XCTR and YCTR). XJOY is -1
- if the stick is moved to the left, 1 if the stick is moved to the
- right, and 0 if the stick is not moved horizontally. YJOY is -1 if
- the stick is moved up, 1 if the stick is moved down, and 0 if the
- stick is not moved vertically.
-
- The advantage of this system is that the screen player can be
- moved very simply in relationship to the joystick by adding the XJOY
- and YJOY values to the current position and using the LOCATE statement
- (liens 220 and 240). The sensitivity of the joystick can be adjusted
- by changing the value in the ABS test (lines 200-210). As shown, the
- joystick must be moved at least 10 increments in the desired direction
- for the change to register. This prevents small jiggles of the stick
- from causing unwanted movement. The test in line 230 prevents the
- player from leaving the maze. The SCREEN function returns 0 if no
- character has been printed in a position, while a maze path position
- will hold the value defined by HL in the maze-drawing routine.
-
- One additional step is required to use this joystick routine.
- Each joystick returns slightly different readings, so it's difficult
- to predict what the values for the center coordinates will be. Thus,
- it's necessary to calibrate the joystick at the start of every program
- that reads it. The following lines show how this can be done:
-
- 10 CLS:WIDTH 40:STRIG ON:PRINT "Press fire button to set center position."
- 20 IF STRIG(0)=0 THEN 20
- 30 XCTR=STICK(0):YCTR=STICK(1)
-